/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2011-12-12     Yi Qiu      first version
 */
#include <rtthread.h>
#include <drivers/usb_host.h>

#define USB_HOST_CONTROLLER_NAME      "usbh"

struct usb_cleanup_msg
{
    void (*cleanup)(void *p);
    void *usrdata;
};

static struct rt_messagequeue _hmq;
static int _hmqbuf[8];

static void usb_cleanup(void)
{
    struct usb_cleanup_msg msg;

    if (rt_mq_recv(&_hmq, &msg, sizeof(msg), 0) == RT_EOK)
    {
        msg.cleanup(msg.usrdata);
    }
}

static void usb_cleanup_init(void)
{
    rt_mq_init(&_hmq, "uhm", _hmqbuf,
               sizeof(struct usb_cleanup_msg), sizeof(_hmqbuf), 0);

    rt_thread_idle_sethook(usb_cleanup);
}

int rt_usbh_cleanup_submit(void (*cleanup)(void*), void *usrdata)
{
    struct usb_cleanup_msg msg;

    msg.cleanup = cleanup;
    msg.usrdata = usrdata;

    return rt_mq_send(&_hmq, &msg, sizeof(msg));
}

/**
 * This function will initialize the usb host stack, all the usb class driver and
 * host controller driver are also be initialized here.
 * 
 * @return none.
 */
int rt_usb_host_init(void)
{
    ucd_t drv;
    rt_device_t uhc;    

    uhc = rt_device_find(USB_HOST_CONTROLLER_NAME);
    if(uhc == RT_NULL)
    {
        rt_kprintf("can't find usb host controller %s\n", USB_HOST_CONTROLLER_NAME);
        return -RT_ERROR;
    }

    /* initialize usb hub */
    rt_usbh_hub_init((uhcd_t)uhc);

    /* initialize class driver */
    rt_usbh_class_driver_init();

    /* register hub class driver */
    drv = rt_usbh_class_driver_hub();
    rt_usbh_class_driver_register(drv);

    /* initialize usb host controller */
    rt_usb_hcd_start((uhcd_t)uhc);

    usb_cleanup_init();

    return 0;
}
INIT_COMPONENT_EXPORT(rt_usb_host_init);
